﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.SharePoint;

namespace SPRepository
{
    public class SPGenericRepository<TT, TD> : IRepository<TT, TD>
        where TT : IContentType<TD>, new()
        where TD : class, IContentTypeDto
    {
        private readonly SPList _list;

        public SPGenericRepository(SPList list)
        {
            _list = list;
        }

        public virtual SPList List
        {
            get { return _list; }
        }

        public virtual IEnumerable<TD> GetAll()
        {
            var contentTypeId = new TT().GetContentTypeIdDefinition();

            var caml = String.Format(SPQueryUtilities.FilterOnContentTypeIdCamlTemplate, contentTypeId);
            var spQuery = new SPQuery();
            spQuery.Query = caml;

            var filteredItems = List.GetItems(spQuery);
            var castedItems = filteredItems.Cast<SPListItem>();

            return DtoUtilities.ConvertToDto<TT, TD>(castedItems);
        }

        public virtual TD Get(int id)
        {
            var item = List.Items.GetItemById(id);
            return new TT().Get(item);
        }

        public virtual void Update(TD dto)
        {
            if (dto == null)
            {
                return;
            }
            var item = List.Items.GetItemById(dto.Id.Value);
            Update(item, dto);
        }

        public virtual void Delete(TD dto)
        {
            if (dto == null)
            {
                return;
            }
            List.Items.DeleteItemById(dto.Id.Value);
        }

        public virtual void Delete(int id)
        {
            List.Items.DeleteItemById(id);
        }

        public virtual void Delete(IEnumerable<TD> dtos)
        {
            if (dtos == null)
            {
                return;
            }

            foreach (var dto in dtos)
            {
                this.Delete(dto);
            }
        }

        protected static void Update(SPListItem item, TD dto)
        {
            if (item == null)
            {
                return;
            }
            new TT().Update(item, dto);
            item.Update();
        }
    }
}